/*
 * table_CcDefChain_t.c
 *
 *  Created on: 2012-5-14
 *      Author: guanxiaoying
 */

#include "../../parser/coredef.h"


#define TableSize  (sizeof(CCDEFCHAIN))
#define TableType  PCCDEFCHAIN
#define stTable stCCSymChainManager.memoryBlocks
#define maxTable stCCSymChainManager.maxRecordNum
#define  maxNumPerBlk  (stCCSymChainManager.astMaxNum_Block)
typedef struct _CCDEFCHAIN
{
	AST astSym;
	RBTREE rbtree;
} CCDEFCHAIN, *PCCDEFCHAIN;


/* get the object */
static TABLEMANAGER stCCSymChainManager = {
//		U4                  usIdx;
		0,
//		PSZ				    con_pszName;    constant
		__FILE__,
//		U2					con_usSize;		constant
		TableSize,
//		U2					block_num;	　　　　　　　Reset clear  際　要
		0,
//		S4					astMaxNum_Block;     １回設定のみ
		0,
//		S4					astTabNum_LastPage; 　　　　Reset clear  際　要
		0,
//		S4					astMaxNum_LastPage;     Reset clear  際　要
		0,
//		U4					ulMaxByte;	　　　　　　　　　　クリアしない
		0,
//		U4					con_minPageSize;　　　　　　　　　　constant
		0
};
static VOID resetListener( U4  procid, U2 index )
{
	if( procid == stCCSymChainManager.u4Idx )
	{
		if( index > 0 && index < MAX_VOLUMN_OF_TABLE )
		{
			stTable[ index-1] = NULL;
		}
	}
}
static TableType core_getTable( AST index )
{
	TableType temp = (TableType)Check_Com( &stCCSymChainManager, resetListener, index );
	if( temp != NULL ){
		if( temp != NULL ){ return &temp[index%maxNumPerBlk]; } return NULL;
	}
	return NULL;
}


static BOOL ClearTable( VOID )
{
	return Clear_Com( &stCCSymChainManager );
}
static BOOL ResetTable( VOID )
{
	return Reset_Com( &stCCSymChainManager );
}
static BOOL AllocTable( AST astReqArg )
{
	return AllocTable_Com( &stCCSymChainManager, astReqArg, resetListener );
}
static AST getMaxLineNum( VOID ){
	return maxTable;
}
/* give up the way that defining get/set function pointer in the struct,
 * because of memory volume.
 */
//	IDX_DECSYMCHAIN
/*  get method */
static AST  getParameter( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->astSym;
}
/* set method */
static AST  setParameter( AST index, AST idx )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		assert_index( maxTable, index, idx );
		return 0;
	}
	return pTbl->astSym = idx;
}

static AST getLeft( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.astLeftChild;
}
static AST setLeft( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.astLeftChild = value;
}
static AST getRight( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.astRightChild;
}
static AST setRight( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.astRightChild = value;
}
static AST getParent( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.astParent;
}
static AST setParent( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.astParent = value;
}
static U2 getColor( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.lColor;
}
static U2 setColor( AST index, U2 value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.lColor = value;
}
//ACCESS_IDX_FIELD
static AST getIndex( AST index )
{
	return getParameter(index);
}

static ACCESS_RBTREE stAccessRbtree =
{
		AllocTable,
		getMaxLineNum,
		getIndex,
		{
				getLeft,
				setLeft
		},
		{
				getRight,
				setRight
		},
		{
				getParent,
				setParent
		},
		{
				getColor,
				setColor
		}
};
static S4 cmp_sym_str( AST astIndex, VOID *data ){
	PSZ name = (PSZ)data;
	PSZ sym_tree = stSymbolInfoAccess.name.get( astIndex );
	S4  nCmp;
	if( str_length( sym_tree) == 0
		&& str_length( name ) == 0 ){
		return RBT_FOUND;
	}
	nCmp = strcmp( name, sym_tree );
	if( nCmp < 0 ){
		return RBT_LESS;
	}else if( nCmp > 0 ){
		return RBT_LARGER;
	}
	return RBT_FOUND;

}
static AST findSymbol( AST root, PSZ name ){
	AST astRet;
	S4 nRet;
	nRet = FindData( &stAccessRbtree, root, name, &astRet, cmp_sym_str );
	if( nRet == RBT_FOUND ){
		return astRet;
	}
	return 0;
}
static AST addSymbol( AST root, AST *proot, PSZ name ){
	AST astRet;
	AST astNew=0;
	S4 nRet;
	BOOL bRet;
	nRet = FindData( &stAccessRbtree, root, name, &astRet, cmp_sym_str );
	if( nRet == RBT_FOUND ){
		return astRet;
	}

	bRet = InsertData( &stAccessRbtree, nRet, astRet, &root, &astNew );
	if( bRet == FALSE )
	{
		return 0;
	}
	if( proot != NULL ){
		*proot = root;
	}
	return astNew;
}
const CCDEFCHAIN_ACCESS stCCDefSymChainAccess = {
		ClearTable,
		ResetTable,
		AllocTable,
		getMaxLineNum,
		{
				getParameter,
				setParameter
		},
		findSymbol,
		addSymbol
};
